//抽象工厂模式
#include<iostream>
#include<memory>
using namespace std;

class Fruit{
    public:
    virtual void show(){
        cout<<"这是一个水果"<<endl;
    }
};
class Apple:public Fruit{
    public:
    void show() override{
        cout<<"这是一个苹果"<<endl;
    }
};
class Banana:public Fruit{
    public:
    void show() override{
        cout<<"这是一个香蕉"<<endl;
    }
};
class Animal{
    public:
    virtual void voice(){
        cout<<"动物叫"<<endl;
    }
};
class Dog:public Animal{
    public:
    void voice() override{
        cout<<"汪汪汪"<<endl;
    }
};
class Cat:public Animal{
    public:
    void voice() override{
        cout<<"喵喵喵"<<endl;
    }
};
class Factor{
    public:
    virtual shared_ptr<Fruit> getFruit(const string& name)=0;
    virtual shared_ptr<Animal> getAnimal(const string& name)=0;
};
class FruitFactor:public Factor{
    public:
    shared_ptr<Animal> getAnimal(const string& name) override{
        return make_shared<Animal>();
    }
    shared_ptr<Fruit> getFruit(const string& name) override{
        if(name=="苹果"){
            return make_shared<Apple>();
        }else if(name=="香蕉"){
            return make_shared<Banana>();
        }
        return make_shared<Fruit>();
    }
};
class AnimalFactor:public Factor{
    public:
    shared_ptr<Fruit> getFruit(const string& name) override{
        return make_shared<Fruit>();
    }
    shared_ptr<Animal> getAnimal(const string& name) override{
        if(name=="小狗"){
            return make_shared<Dog>();
        }else if(name=="小猫"){
            return make_shared<Cat>();
        }
        return make_shared<Animal>();
    }
};
class FactorManager{
    public:
    static shared_ptr<Factor> getFactor(const string& name){
        if(name=="水果"){
            return make_shared<FruitFactor>();
        }else{
            return make_shared<AnimalFactor>();
        }
    }
};

int main()
{
    shared_ptr<Factor> factor=FactorManager::getFactor("水果");
    shared_ptr<Fruit> fruit=factor->getFruit("苹果");
    fruit->show();
    fruit=factor->getFruit("香蕉");
    fruit->show();

    factor=FactorManager::getFactor("小动物");
    shared_ptr<Animal> animal=factor->getAnimal("小狗");
    animal->voice();
    animal=factor->getAnimal("小猫");
    animal->voice();
    return 0;
}